<?php

namespace App\Kuafu\Dashboard\Service;

use App\Exceptions\BaseException;
use App\Kuafu\Common\Enum\CodeEnum;
use App\Kuafu\Config\Model\ConfigModel;
use App\Kuafu\Config\Service\ConfigService;
use App\Kuafu\Mybank\Model\MybankEntryModel;
use App\Kuafu\Mybank\Service\MybankEntryService;
use App\Kuafu\Mybank\Service\MybankService;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Sys\Model\Menus;
use App\Kuafu\Sys\Service\MenusService;
use App\Kuafu\User\Enum\PermissionsEnum;
use App\Kuafu\User\Enum\RoleCodeEnum;
use App\Kuafu\User\Model\Permissions;
use App\Kuafu\User\Model\RolePermissionMappings;
use App\Kuafu\User\Model\UserRoleMapping;
use App\Kuafu\User\Model\UserUseServiceLogModel;
use App\Kuafu\User\Service\PermissionsService;
use App\Kuafu\Base\Enum\BaseCodeEnum;
use App\Kuafu\Base\Service\BaseService;
use App\Library\KfHttp\TigerCurl;
use App\Remote\Tiger\OpenShop\OpenShopRemote;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class DashboardService extends BaseService
{
    /**
     * 获取系统菜单
     * 夸父订货系统 依赖此方法
     *
     * @param int $roleId
     * @param int $platform
     * @return array
     */
    public static function getMenusV2(array $roleList, int $platform = CodeEnum::PLATFORM_B_BRAND)
    {
        // 获取所有权限
        $permissionAll = Permissions::getAll($platform)->toArray();

        // 获取当前用户的权限
        $rolePermissionAll = RolePermissionMappings::getAllByRoleList($roleList)->keyBy('permissionId')->toArray();

        // 判断用户当前权限
        foreach ($permissionAll as $key => &$permissionValue) {
            if (!key_exists($permissionValue['id'], $rolePermissionAll)) {
                unset($permissionAll[$key]);
            }
            $permissionValue['enable'] = key_exists($permissionValue['id'], $rolePermissionAll) ? 1 : 0;
        }

        // 获取所有菜单目录
        switch ($platform) {
            case CodeEnum::PLATFORM_DEFAULT:
            case CodeEnum::PLATFORM_B_BRAND:
                $menusAll = MenusService::getWebMenusList();
                break;
            case CodeEnum::PLATFORM_POS:
                $menusAll = MenusService::getPosMenusList();
                break;
            case CodeEnum::PLATFORM_BUSINESS:
                // 谁再把我代码合并没了，我就拿砍刀了
                $menusAll = Menus::getAll(Menus::TYPE_SHOP);
                break;
            default:
                $menusAll = MenusService::getWebMenusList();
        }
        $menusAll = $menusAll->each(function ($menus) {
            $menus->componentName = $menus->alias;
            unset($menus->alias);
            unset($menus->status);
        })->toArray();

        // 整理菜单
        $mixedList = PermissionsService::formatMenusWithPermissionsSp($menusAll, $permissionAll);

        // 组成无限极菜单
        $mixedList = MenusService::formatMenus($mixedList);
        $mixedList = array_values($mixedList);
        // 剔除没有权限的菜单
        MenusService::filterNoAccessMenus($mixedList);

        return $mixedList;
    }

    // 纯用户控制权限
    public static function getMerchantButtonList($userId, $shopId)
    {
        $actions = [];
        // 网商钱包展示权限
        if (MybankEntryService::checkUserMybankAccess($userId)) {
            $actions[] = PermissionsEnum::PERMISSION_APP_MYBANK_WALLET;
        }

        return $actions;
    }

    /**
     * 获取我的服务
     * @param $userId
     * @param $shopId
     * @param $actions
     * @param string $appVersion
     * @return array
     */
    public static function getMyServeByPower($userId, $shopId, $actions, string $appVersion = ''): array
    {
        //获取我的服务列表
        $sever = PermissionsEnum::MY_SERVICE_MAPPING;
        if ($appVersion && $sever) {// APP大于此版本号则显示
            foreach ($sever as $k => $v) {
                if (isset($v['version']) && version_compare($v['version'], $appVersion, '>')) {
                    unset($sever[$k]);
                }
            }
        }

        // 特殊处理
        $special = self::specialProvincePower($shopId, 0, $userId);

        $whiteShopIds = json_decode(ConfigModel::getConfigByTypeKeyOne('pay', 'mybank.whiteShopIds')->value ?? '[]', true) ?? [];

        // 白名单模式关闭
        if ($whiteShopIds == []) {
            $isWalletPower = self::getWalletPower($userId, $shopId);
        } elseif (in_array($shopId, $whiteShopIds)) {

            // 在白名单里 - 直接显示入口
            $isWalletPower = true;
        } else {

            // 兼容模式 - 已开通的用户显示入口
            $isWalletPower = MybankEntryService::checkUserMybankAccess($userId);
        }

        if (!$isWalletPower) {
            unset($sever[PermissionsEnum::POWER_APP_MY_BANK_WALLET]);
        } else {

            if ($special) {
                // 特殊情况 判断未开通
                $sever[PermissionsEnum::POWER_APP_MY_BANK_WALLET]['new'] = MybankEntryService::checkUserMybankAccess($userId) == false;
            } else {
                // 非特殊条件 走之前的流程

                //判断当前用户是否已经点击过钱包
                $clickWallet = UserUseServiceLogModel::query()
                    ->where('type', UserUseServiceLogModel::TYPE_WALLET)
                    ->where('userId', $userId)
                    ->count();

                $sever[PermissionsEnum::POWER_APP_MY_BANK_WALLET]['new']  = !$clickWallet;
            }
            $sever[PermissionsEnum::POWER_APP_MY_BANK_WALLET]['open'] = (MybankEntryService::registerStatus($userId)['status'] ?? 0) == MybankEntryModel::STATUS_3;
        }

        //判断是否拥有开店订单的权限
        if (!in_array(PermissionsEnum::POWER_APP_MT_OPEN_SHOP_ORDER, $actions)) {
            unset($sever[PermissionsEnum::POWER_APP_MT_OPEN_SHOP_ORDER]);
        }
        return array_values($sever);
    }


    /**
     * 判断用户是否拥有权限
     * @param $userId
     * @param $shopId
     * @return bool
     */
    public static function getWalletPower($userId, $shopId): bool
    {
        //拥有订货权限或者是店长权限的展示钱包
        $roleManagerId = config('merchant.manager_role_id');
        $roleOrderId   = config('merchant.order_role_id');
        return UserRoleMapping::query()
            ->where('shopId', $shopId)
            ->where('userId', $userId)
            ->with([
                'userRel' => function ($query) {
                    $query->where('status', \App\Kuafu\User\Enum\CodeEnum::USER_STATUS_USE);
                }
            ])
            ->whereIn('roleId', [$roleManagerId, $roleOrderId])
            ->exists();
    }


    public static function bottomButtonShow($userId, $shopId): array
    {
        // 特殊处理
        $special = self::specialProvincePower($shopId, 0, $userId);

        $button = PermissionsEnum::BOTTOM_BUTTON_MAPPING;

        // 『消息』总数
        try {
            $msgNum = (int)collect(TigerCurl::getIns()->do('internal/common/getUserNotifyList', ['userId' => $userId, 'shopId' => $shopId], 'GET')['data'] ?? [])->sum('unReadNum');
        } catch (\Exception $e) {
            $msgNum = 0;
        }

        if ($msgNum > 0) {
            $button[PermissionsEnum::BOTTOM_BUTTON_MESSAGE]['num'] = $msgNum;
            $button[PermissionsEnum::BOTTOM_BUTTON_MESSAGE]['showType'] = PermissionsEnum::BOTTOM_BUTTON_SHOW_TYPE_NUMBER;
            $button[PermissionsEnum::BOTTOM_BUTTON_MESSAGE]['showStatus'] = true;
        }

        return collect($button)->map(function ($item, $key) use ($userId, $shopId, $special){
            if ($key == PermissionsEnum::BOTTOM_BUTTON_MY) {
                // TODO 判断有没有钱包权限
                $isWalletBySystemPower = self::getWalletPower($userId, $shopId);

                $isWallet = MybankEntryService::checkUserMybankAccess($userId);

                //判断当前用户是否已经点击过钱包
                $clickCount = UserUseServiceLogModel::query()
                    ->where('type', UserUseServiceLogModel::TYPE_WALLET)
                    ->where('userId', $userId)
                    ->count();

                if ($special) {
//                    $whiteShopIds = json_decode(ConfigModel::getConfigByTypeKeyOne('pay', 'mybank.whiteShopIds')->value ?? '[]', true) ?? [];
//
//                    // 白名单模式关闭
//                    if (!empty($whiteShopIds)) {
//                        $whitePower = in_array($shopId, $whiteShopIds);
//                    } else {
//                        $whitePower = true;
//                    }

                    // 特殊情况并且拥有权限
                    if ($isWalletBySystemPower && !$isWallet) {
                        $item['showStatus'] = true;
                    }
                } else {
                    // 非特殊情况按照之前流程处理
                    if ($isWallet && !$clickCount) {
                        $item['showStatus'] = true;
                    }
                }
            }
            return $item;
        })->values()->toArray();
    }

    /**
     * @param $shopId
     * @param int $provinceCode
     * @param int $userId
     * @return bool
     */
    public static function specialProvincePower($shopId, int $provinceCode = 310000, int $userId = 0): bool
    {
        $filterUserIds = json_decode((string)optional(ConfigModel::getConfigByTypeKeyOne('myBank', 'filterUserIds'))->value, true) ?: [];

        if ($userId && in_array($userId, $filterUserIds)) {
            return false;
        }

        // 获得门店信息
        $shopExist = Shop::query()
            ->where('id', $shopId)
            ->when($provinceCode, function ($query) use ($provinceCode) {
                $query->where('province', $provinceCode);
            })
            ->exists();

        $deadline = ConfigModel::getConfigByTypeKeyOne('myBank', 'pushNotifyDeadline');
        // 特殊处理
        $special = false;
        if ($shopExist && time() < Carbon::createFromDate(optional($deadline)->value)->endOfDay()->timestamp) {
            $special = true;
        }

        return $special;
    }

    /**
     * 商家端-》 我的 -》 去哪儿选铺子展示状态
     *
     * @param array $actions
     * @param int $shopId
     * @return bool
     * @throws BaseException
     */
    public static function intendedSiteSelectionShowStatus(array $actions, int $shopId): bool
    {
        // todo 权限配置
        $auth = in_array("app.my.intendedSiteSelection", $actions);

        // todo 判断灰度门店
        $shopLists = attributeGet(
            ConfigService::getConfigDetail("merchantMine","moduleShopLists", 0),
            "value.intendedSiteSelection.shopLists",
            []
        );

        return $auth && (empty($shopLists) || in_array($shopId, $shopLists));
    }

    /**
     * 判断是否拥有资质报告权限
     */
    public static function qualificationReportPower($userId, $shopId): bool
    {
        // 判断是否为店长
        $checkMerchantManager = UserRoleMapping::query()
            ->where('userId', $userId)
            ->where('roleId', config('merchant.manager_role_id'))
            ->where('shopId', $shopId)
            ->exists();
        if (!$checkMerchantManager) {
            return false;
        }

        // 判断是否存在灰度门店
        $configJson = (string)ConfigModel::query()
            ->where('type', 'supplier')
            ->where('key', 'qualificationReportPower')
            ->value('value');
        if (!strlen($configJson)) {
            return false;
        }
        $configArr = json_decode($configJson, true);

        // 为空则全量
        if (!count($configArr)) {
            return true;
        }

        // 存在灰度门店
        if (count($configArr) && in_array($shopId, $configArr)) {
            return true;
        }

        return false;
    }

    /**
     * 判断是否拥有门店自检权限
     */
    public static function shopCheckSelfPowerRes($userId, $shopId): bool
    {
        // // 判断是否为店长
        // $checkMerchantManager = UserRoleMapping::query()
        //     ->where('userId', $userId)
        //     ->where('roleId', config('merchant.manager_role_id'))
        //     ->where('shopId', $shopId)
        //     ->exists();
        // if (!$checkMerchantManager) {
        //     return false;
        // }

        // 判断是否存在灰度门店
        $configJson = (string)ConfigModel::query()
            ->where('type', 'cruise')
            ->where('key', 'shopCheckSelfPower')
            ->value('value');
        if (!strlen($configJson)) {
            return false;
        }
        $configArr = json_decode($configJson, true);

        // 为空则全量
        if (!count($configArr)) {
            return true;
        }

        // 存在灰度门店
        if (count($configArr) && in_array($shopId, $configArr)) {
            return true;
        }

        return false;
    }

    /**
     * 获得应用状态 标记
     * @param array $actions
     * @param int $shopId
     * @return array
     */
    public static function getActionStatus(array $actions, int $shopId): array
    {
        $list = [];
        foreach ($actions as $action){
            try{
                switch ($action){
                    case 'app.user.getUserList':
                        $list[] = self::getActionStatusAppUserCard($shopId,$action);
                        break;
                    case 'app.shop.config.license':
                        $list[] = self::getActionStatusAppShopLicense($shopId,$action);
                        break;
                }
            } catch (\Exception $exception){
                Log::error($exception);
            }
        }

        return $list;
    }

    //证件缺失
    public static function getActionStatusAppUserCard($shopId,$actionName)
    {
        $userList = UserRoleMapping::getUserIdsByShopIds($shopId, [RoleCodeEnum::ROLE_BUSINESS_TYPE, RoleCodeEnum::ROLE_POS_TYPE]);

        $num = collect($userList)->where('inShop', UserRoleMapping::IN_SHOP_ON)->where('cardStatus', '!=', '')->unique('userId')->count();

        return [
            "name"       => $actionName,
            "showStatus" => (bool)$num,
            "showType"   => PermissionsEnum::BOTTOM_BUTTON_SHOW_TYPE_NUMBER,
            "num"        => $num
        ];
    }

    /**
     * @param int $shopId
     * @param string $actionName
     * @return array
     * @throws BaseException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function getActionStatusAppShopLicense(int $shopId,string $actionName): array
    {
        if ($list = self::cacheGetFromShopAction($shopId,$actionName)){
            return  $list;
        }
        $list = OpenShopRemote::getShopLicenseStatus([$shopId]);

        $listByShopId = array_column($list,null,'shopId');

        $res = [
            "name"       => $actionName,
            "showStatus" => (bool)($listByShopId[$shopId]['showStatus'] ?? false),
            "showType"   => PermissionsEnum::BOTTOM_BUTTON_SHOW_TYPE_NUMBER,
            "num"        => (int)($listByShopId[$shopId]['num'] ?? 0)
        ];

        self::cacheValueForShopAction($shopId,$actionName,$res,886400);

        return $res;
    }

    public static function cacheKeyOfShopAction(int $shopId, string $actionName): string
    {
        return "REMOTE:DashboardService:cacheKeyOfShopAction:{$actionName}:{$shopId}";
    }

    /**
     * @param int $shopId
     * @param string $actionName
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function cacheGetFromShopAction(int $shopId, string $actionName): array
    {
        $key = self::cacheKeyOfShopAction($shopId, $actionName);
        return Cache::store('redis')->get($key) ?: [];
    }

    /**
     * @param int $shopId
     * @param string $actionName
     * @param array $value
     * @param int|null $cacheSec
     * @return bool
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function cacheValueForShopAction(
        int $shopId,
        string $actionName,
        array $value,
        int $cacheSec = null
    ): bool {
        $key = self::cacheKeyOfShopAction($shopId, $actionName);

        return Cache::store('redis')->set($key, $value, $cacheSec);
    }


}
